home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_02 / misc / longcalc.c < prev    next >
C/C++ Source or Header  |  1994-03-20  |  4KB  |  157 lines

  1. /*
  2.  * This program implements a simple "calculator" using LONG numbers.
  3.  * It demonstrates the "long" math functions from the library.
  4.  *
  5.  * Copyright 1994 Dave Dunfield
  6.  * All rights reserved.
  7.  *
  8.  * Permission granted for personal (non-commercial) use only.
  9.  *
  10.  * Compile command: cc longcalc -fop
  11.  */
  12. #include <stdio.h>
  13. #include <window.h>
  14.  
  15. /*
  16.  * Default LONG number size is 4 bytes (32 bits). If you wish to change
  17.  * this (up to 256 bits), edit the 'LSIZE EQU 4' in the LONGMATH.ASM
  18.  * file in the library. You also have to adjust the sizes of all array
  19.  * declarations which are to contain LONG numbers. For this demo,
  20.  * just adjust the constant defined below.
  21.  */
  22. #define    LSIZE    4        /* 32 bit numbers */
  23.  
  24. /*
  25.  * Long number registers
  26.  */
  27. char reg[LSIZE], temp1[LSIZE],    temp2[LSIZE];
  28.  
  29. /*
  30.  * Input/Output Digit buffer. Note that we use an approximation to
  31.  * compute the number of digits required based on the size of the
  32.  * LONG numbers.
  33.  */
  34. char buffer[(LSIZE*25)/10+1];
  35.  
  36. /*
  37.  * This temporary variable used by the LONGMATH functions is useful,
  38.  * because it will contain the remainder after a division.
  39.  */
  40. extern char Longreg[];
  41.  
  42. /*
  43.  * Convert a LONG number into a printable string
  44.  */
  45. long_to_string(string, n1, base)
  46.     unsigned char *string, *n1, base;
  47. {
  48.     unsigned sp;
  49.     unsigned char c, stack[(LSIZE*25)/10+1];
  50.  
  51.     longcpy(temp2, n1);
  52.     longset(temp1, base);
  53.     
  54.     /* Stack up digits in reverse order */
  55.     sp = 0;
  56.     do {
  57.         longdiv(temp2, temp1);
  58.         stack[sp++] = ((c = *Longreg) > 9) ? c + '7' : c + '0'; }
  59.     while(longtst(temp2));
  60.  
  61.     /* Unstack digits into output buffer */
  62.     do
  63.         *string++ = stack[--sp];
  64.     while(sp);
  65.     *string = 0;
  66. }
  67.  
  68. /*
  69.  * Convert a string into a LONG number
  70.  * Returns character terminating conversion.
  71.  */
  72. string_to_long(string, n1, base)
  73.     unsigned char *string, *n1, base;
  74. {
  75.     unsigned char c;
  76.  
  77.     longset(n1, 0);
  78.  
  79.     while(c = *string++) {
  80.         if(isdigit(c))
  81.             c -= '0';
  82.         else if(c >= 'a')
  83.             c -= ('a' - 10);
  84.         else if(c >= 'A')
  85.             c -= ('A' - 10);
  86.         else
  87.             break;
  88.         if(c >= base)
  89.             break;
  90.         longset(temp1, base);
  91.         longmul(n1, temp1);
  92.         longset(temp1, c);
  93.         longadd(n1, temp1); }
  94.     return c;
  95. }
  96.  
  97. /*
  98.  * Main calculator program
  99.  */
  100. main()
  101. {
  102.     unsigned char c, op;
  103.     char *ptr;
  104.  
  105.     wopen(0, 0, 80, 25, WSAVE|WCOPEN|WBOX1|WWRAP|WSCROLL|NORMAL);
  106.     wputs("Long Number Calculator,  Supports: + - * / % = ENTER(clear) ESC(exit)\n");
  107.  
  108. clear:            /* Clear the calculator by forcing a copy operation */
  109.     wputs("Clear\n");
  110.     op = '=';
  111.     ptr = buffer;                        /* Begin processing a number */
  112.  
  113.     for(;;) {                            /* Continue processing a number */
  114.         while(isdigit(c = wgetc())) {        /* Collect digits into string */
  115.             wputc(c);
  116.             *ptr++ = c; }
  117.         *ptr = 0;                            /* Zero terminate */
  118.         string_to_long(buffer, temp2, 10);    /* Get LONG value for operation */
  119.     
  120.         switch(op) {                        /* Perform pending operation */
  121.             case '=' :    longcpy(reg, temp2);    break;
  122.             case '+' :    longadd(reg, temp2);    break;
  123.             case '-' :    longsub(reg, temp2);    break;
  124.             case '*' :    longmul(reg, temp2);    break;
  125.             case '/' :    longdiv(reg, temp2);    break;
  126.             case '%' :    longdiv(reg, temp2); longcpy(reg, Longreg); }
  127.     
  128. operate:                                    /* Process next operator */
  129.         wputc(c);                            /* Echo next command */
  130.         switch(c) {
  131.             case 0x1B:                        /* Exit */
  132.                 wclose();
  133.                 return;
  134.             default:                        /* Unrecognized */
  135.                 wputs(" ?Invalid input... ");
  136.             case '\n' :                        /* Clear */
  137.                 goto clear;
  138.             case '=' :                        /* Display results */
  139.                 long_to_string(buffer, reg, 10);
  140.                 wputs(buffer);
  141.                 if(!isdigit(c = wgetc()))    /* Chained operation */
  142.                     goto operate;
  143.                 wputc('\n');
  144.                 wputc(c);
  145.                 op = '=';
  146.                 ptr = buffer;
  147.                 *ptr++ = c;
  148.                 continue;
  149.             case '+' :                        /* Addition */
  150.             case '-' :                        /* Subtraction */
  151.             case '*' :                        /* Multiplication */
  152.             case '/' :                        /* Division */
  153.             case '%' :                        /* Modulus */
  154.                 op = c; }
  155.         ptr = buffer; }                        /* Reset number pointer */
  156. }
  157.